package cn.fscode.code.generator.manager;

import cn.fscode.code.generator.model.WordDataUnderTitle;
import cn.fscode.code.generator.model.WordTable;
import cn.fscode.code.generator.model.WordTableCell;
import cn.fscode.code.generator.model.WordTableRow;
import cn.fscode.commons.tool.core.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.*;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author shenguangyang
 */
@Service
public class DocManager extends WordTableManager {
    public static void main(String[] args) throws IOException {
        DocManager docManager = new DocManager();
        List<WordDataUnderTitle> wordDataList = docManager.getWordDataList("D:\\test.docx");
        System.out.println("end");
    }

    @PostConstruct
    public void init() {
        wordTableManagerMap.put(WordFileType.DOC, this);
    }

    @Override
    public List<WordDataUnderTitle> getWordDataList(String path) throws IOException {
        InputStream is = Files.newInputStream(Paths.get(path));
        HWPFDocument doc = new HWPFDocument(is);
        Range range = doc.getRange();
        //读列表
        List<WordDataUnderTitle> wordDataList = this.readList(range);
        List<WordTable> wordTables = this.readTable(range);

        int wordTableIndex = 0;
        for (WordDataUnderTitle wordData : wordDataList) {
            int tableNum = wordData.getTableNum();
            if (tableNum <= 0) {
                continue;
            }
            List<WordTable> wordTableList = wordData.getWordTableList();
            for (int i = wordTableIndex; i < wordTables.size() && i < (wordTableIndex + tableNum); i++) {
                wordTableList.add(wordTables.get(i));
            }
            wordTableIndex += tableNum;
        }
        return wordDataList;
    }

    /**
     * 读表格
     * 每一个回车符代表一个段落，所以对于表格而言，每一个单元格至少包含一个段落，每行结束都是一个段落。
     */
    private List<WordTable> readTable(Range range) {
        // 遍历range范围内的table。
        TableIterator tableIter = new TableIterator(range);
        Table table;
        TableRow row;
        TableCell cell;
        List<WordTable> resp = new ArrayList<>();
        while (tableIter.hasNext()) {
            table = tableIter.next();
            int rowNum = table.numRows();
            WordTable wordTable = new WordTable();
            for (int j = 0; j < rowNum; j++) {
                row = table.getRow(j);
                WordTableRow wordTableRow = new WordTableRow();
                int cellNum = row.numCells();
                if (cellNum <= 0) {
                    continue;
                }
                for (int k = 0; k < cellNum; k++) {
                    WordTableCell wordTableCell = new WordTableCell();
                    cell = row.getCell(k);
                    wordTableCell.setText(cell.text().trim());
                    wordTableRow.getCells().add(wordTableCell);
                }
                wordTable.getRows().add(wordTableRow);
            }
            resp.add(wordTable);
        }
        return resp;
    }

    /**
     * 读取word list
     *
     * @return key: 标题名 value: word数据
     */
    private List<WordDataUnderTitle> readList(Range range) {
        int num = range.numParagraphs();
        Paragraph para;
        boolean hasTable = false;
        Map<String, WordDataUnderTitle> data = new LinkedHashMap<>();
        String currentParaText = "";
        for (int i = 0; i < num; i++) {
            para = range.getParagraph(i);
            if (para.isInList()) {
                // 这里只获取标题以及标题下面的表数量, 普通文本不要
                if (para.text().contains("\u0007") || para.getIlvl() == 0) {
                    continue;
                }
                if (StringUtils.isEmpty(currentParaText)) {
                    currentParaText = para.text()
                            .replace("\r\n", "").replace("\r", "");
                }
                if (hasTable) {
                    WordDataUnderTitle readList = data.computeIfAbsent(currentParaText, v -> new WordDataUnderTitle());
                    readList.setTableNum(readList.getTableNum() + 1);
                    hasTable = false;
                }
                if (para.getIlvl() == 0) {
                    continue;
                }
                currentParaText = para.text().replace("\r\n", "").replace("\r", "");
                WordDataUnderTitle wordDataUnderTitle = data.computeIfAbsent(currentParaText, v -> new WordDataUnderTitle());
                wordDataUnderTitle.setLevel(para.getIlvl());
                wordDataUnderTitle.setTitle(currentParaText);
            }
            if (para.isInTable()) {
                hasTable = true;
            }
        }
        // 处理最后一个目录下的表
        if (hasTable) {
            WordDataUnderTitle wordDataUnderTitle = data.computeIfAbsent(currentParaText, v -> new WordDataUnderTitle());
            wordDataUnderTitle.setTableNum(wordDataUnderTitle.getTableNum() + 1);
        }
        return new ArrayList<>(data.values());
    }
}
